#define _GNU_SOURCE
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>
#include <string.h>

typedef void (*void_fn)(void);

__attribute__((used)) static void fallback(void) {
    /* keep reachable symbol for dladdr demo */
}

__attribute__((visibility("default")))
int multi_calls_demo(int variant) {
    const char *requested = (variant & 1) ? "libm.so.6" : "libc.so.6";
    void *handle = dlopen(requested, RTLD_NOW | RTLD_LOCAL);
    if (!handle) {
        const char *err = dlerror();
        if (err) {
            fputs(err, stderr);
        }
        return -1;
    }

    void_fn sym = (void_fn)dlsym(handle, (variant & 2) ? "cos" : "puts");

    Dl_info info;
    memset(&info, 0, sizeof(info));
    int has_info = sym ? dladdr((void *)sym, &info) : 0;

    if (!sym || !has_info) {
        dlclose(handle);
        return -2;
    }

    if (info.dli_sname) {
        puts(info.dli_sname);
    }

    dlclose(handle);
    return 0;
}
